import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '../config/config.service';
import { BinanceService } from '../binance/binance.service';
import { RiskAssessment, TradingSignal } from './interfaces/trading.interface';
import { AccountInfo, Position } from '../binance/interfaces/binance.interface';

@Injectable()
export class RiskManagementService {
  private readonly logger = new Logger(RiskManagementService.name);

  constructor(
    private configService: ConfigService,
    private binanceService: BinanceService,
  ) {}

  // 评估当前风险水平
  async assessRisk(
    accountInfo: AccountInfo,
    positions: Position[],
    signal: TradingSignal,
  ): Promise<RiskAssessment> {
    try {
      const currentRisk = this.calculateCurrentRisk(accountInfo, positions);
      const maxAllowedRisk = this.configService.riskPercentage;
      
      // 计算建议仓位大小
      const positionSizeRecommendation = this.calculatePositionSize(
        accountInfo,
        signal,
        currentRisk,
      );

      // 计算止损止盈位
      const stopLossRecommendation = this.calculateStopLoss(signal);
      const takeProfitRecommendation = this.calculateTakeProfit(signal);

      // 计算建议杠杆
      const leverageRecommendation = this.calculateLeverage(currentRisk);

      // 评估风险等级
      const riskLevel = this.evaluateRiskLevel(currentRisk, maxAllowedRisk);

      // 生成风险警告
      const warnings = this.generateRiskWarnings(
        accountInfo,
        positions,
        currentRisk,
        maxAllowedRisk,
      );

      const assessment: RiskAssessment = {
        currentRisk,
        maxAllowedRisk,
        positionSizeRecommendation,
        stopLossRecommendation,
        takeProfitRecommendation,
        leverageRecommendation,
        riskLevel,
        warnings,
      };

      this.logger.log(`风险评估完成: 当前风险 ${currentRisk.toFixed(2)}%, 风险等级 ${riskLevel}`);
      
      return assessment;
    } catch (error) {
      this.logger.error('风险评估失败:', error);
      throw error;
    }
  }

  // 计算当前风险水平
  private calculateCurrentRisk(accountInfo: AccountInfo, positions: Position[]): number {
    if (accountInfo.totalWalletBalance === 0) return 0;

    // 计算总持仓风险
    const totalPositionRisk = positions.reduce((risk, position) => {
      const positionValue = Math.abs(position.positionAmt * position.markPrice);
      const positionRisk = (positionValue / accountInfo.totalWalletBalance) * 100;
      return risk + positionRisk;
    }, 0);

    // 加上未实现盈亏的影响
    const unrealizedPnlRisk = Math.abs(accountInfo.totalUnrealizedPnl / accountInfo.totalWalletBalance) * 100;

    return totalPositionRisk + unrealizedPnlRisk;
  }

  // 计算建议仓位大小
  private calculatePositionSize(
    accountInfo: AccountInfo,
    signal: TradingSignal,
    currentRisk: number,
  ): number {
    let maxRisk = this.configService.riskPercentage;
    
    // 激进模式下增加风险倍数
    if (this.configService.aggressiveMode) {
      maxRisk *= this.configService.aggressiveRiskMultiplier;
      this.logger.log(`激进模式: 风险倍数 ${this.configService.aggressiveRiskMultiplier}x，调整后最大风险: ${maxRisk}%`);
    }
    
    const availableRisk = Math.max(0, maxRisk - currentRisk);
    
    // 基于可用风险计算仓位大小
    const riskAmount = (accountInfo.availableBalance * availableRisk) / 100;
    
    // 基于信号置信度调整仓位大小
    const confidenceMultiplier = signal.confidence / 100;
    
    // 基于最大仓位限制
    let maxPositionSize = this.configService.maxPositionSize;
    
    // 激进模式下增加最大仓位限制
    if (this.configService.aggressiveMode) {
      maxPositionSize *= this.configService.aggressiveRiskMultiplier;
    }
    
    const maxPositionValue = accountInfo.availableBalance * maxPositionSize;
    
    const recommendedValue = Math.min(riskAmount * confidenceMultiplier, maxPositionValue);
    
    // 转换为数量（假设当前价格）
    const currentPrice = signal.price || 0;
    if (currentPrice === 0) return 0;
    
    return recommendedValue / currentPrice;
  }

  // 计算止损位
  private calculateStopLoss(signal: TradingSignal): number {
    if (!signal.price) return 0;

    const stopLossPercentage = this.configService.stopLossPercentage / 100;
    
    if (signal.action === 'BUY') {
      return signal.price * (1 - stopLossPercentage);
    } else if (signal.action === 'SELL') {
      return signal.price * (1 + stopLossPercentage);
    }
    
    return 0;
  }

  // 计算止盈位
  private calculateTakeProfit(signal: TradingSignal): number {
    if (!signal.price) return 0;

    const takeProfitPercentage = this.configService.takeProfitPercentage / 100;
    
    if (signal.action === 'BUY') {
      return signal.price * (1 + takeProfitPercentage);
    } else if (signal.action === 'SELL') {
      return signal.price * (1 - takeProfitPercentage);
    }
    
    return 0;
  }

  // 计算建议杠杆
  private calculateLeverage(currentRisk: number): number {
    const maxRisk = this.configService.riskPercentage;
    
    if (currentRisk >= maxRisk * 0.8) {
      return 1; // 高风险时使用低杠杆
    } else if (currentRisk >= maxRisk * 0.5) {
      return 2; // 中等风险时使用中等杠杆
    } else {
      return 3; // 低风险时可以使用稍高杠杆
    }
  }

  // 评估风险等级
  private evaluateRiskLevel(currentRisk: number, maxAllowedRisk: number): 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL' {
    const riskRatio = currentRisk / maxAllowedRisk;
    
    if (riskRatio >= 1.0) return 'CRITICAL';
    if (riskRatio >= 0.8) return 'HIGH';
    if (riskRatio >= 0.5) return 'MEDIUM';
    return 'LOW';
  }

  // 生成风险警告
  private generateRiskWarnings(
    accountInfo: AccountInfo,
    positions: Position[],
    currentRisk: number,
    maxAllowedRisk: number,
  ): string[] {
    const warnings: string[] = [];

    // 风险水平警告
    if (currentRisk >= maxAllowedRisk) {
      warnings.push(`当前风险水平 ${currentRisk.toFixed(2)}% 超过最大允许风险 ${maxAllowedRisk}%`);
    }

    // 保证金警告
    const marginRatio = accountInfo.totalPositionInitialMargin / accountInfo.totalWalletBalance;
    if (marginRatio > 0.8) {
      warnings.push(`保证金使用率过高: ${(marginRatio * 100).toFixed(2)}%`);
    }

    // 未实现盈亏警告
    const unrealizedPnlRatio = Math.abs(accountInfo.totalUnrealizedPnl / accountInfo.totalWalletBalance);
    if (unrealizedPnlRatio > 0.1) {
      warnings.push(`未实现盈亏占比过高: ${(unrealizedPnlRatio * 100).toFixed(2)}%`);
    }

    // 持仓集中度警告
    if (positions.length === 1) {
      warnings.push('持仓过于集中，建议分散投资');
    }

    // 杠杆警告
    const highLeveragePositions = positions.filter(pos => pos.leverage > 5);
    if (highLeveragePositions.length > 0) {
      warnings.push(`存在高杠杆持仓 (${highLeveragePositions.length}个)`);
    }

    return warnings;
  }

  // 检查是否可以执行交易
  async canExecuteTrade(signal: TradingSignal): Promise<{ canTrade: boolean; reason?: string }> {
    try {
      const accountInfo = await this.binanceService.getAccountInfo();
      const positions = await this.binanceService.getPositions();
      
      const riskAssessment = await this.assessRisk(accountInfo, positions, signal);

      // 检查风险等级
      if (riskAssessment.riskLevel === 'CRITICAL') {
        return {
          canTrade: false,
          reason: '当前风险等级为CRITICAL，禁止新开仓',
        };
      }

      // 检查可用余额
      if (accountInfo.availableBalance < 10) { // 最小余额要求
        return {
          canTrade: false,
          reason: '可用余额不足',
        };
      }

      // 检查建议仓位大小
      if (riskAssessment.positionSizeRecommendation <= 0) {
        return {
          canTrade: false,
          reason: '建议仓位大小为0或负数',
        };
      }

      // 检查信号置信度（支持激进模式）
      const confidenceThreshold = this.configService.aggressiveMode 
        ? this.configService.aggressiveConfidenceThreshold 
        : 40;
        
      if (signal.confidence < confidenceThreshold) {
        return {
          canTrade: false,
          reason: `信号置信度过低: ${signal.confidence}%，当前阈值: ${confidenceThreshold}%`,
        };
      }

      return { canTrade: true };
    } catch (error) {
      this.logger.error('检查交易可行性失败:', error);
      return {
        canTrade: false,
        reason: '风险评估失败',
      };
    }
  }

  // 应急止损检查
  async emergencyStopCheck(): Promise<{ shouldStop: boolean; reason?: string }> {
    try {
      const accountInfo = await this.binanceService.getAccountInfo();
      const positions = await this.binanceService.getPositions();

      // 检查总亏损是否超过阈值
      const totalLossRatio = Math.abs(accountInfo.totalUnrealizedPnl) / accountInfo.totalWalletBalance;
      if (totalLossRatio > 0.15) { // 15%亏损阈值
        return {
          shouldStop: true,
          reason: `总亏损超过15%: ${(totalLossRatio * 100).toFixed(2)}%`,
        };
      }

      // 检查保证金率
      const marginRatio = accountInfo.totalPositionInitialMargin / accountInfo.totalWalletBalance;
      if (marginRatio > 0.9) {
        return {
          shouldStop: true,
          reason: `保证金使用率过高: ${(marginRatio * 100).toFixed(2)}%`,
        };
      }

      // 检查是否有接近强平的持仓
      const dangerousPositions = positions.filter(pos => {
        const liquidationDistance = Math.abs(pos.markPrice - pos.liquidationPrice) / pos.markPrice;
        return liquidationDistance < 0.05; // 距离强平价5%以内
      });

      if (dangerousPositions.length > 0) {
        return {
          shouldStop: true,
          reason: `存在${dangerousPositions.length}个接近强平的持仓`,
        };
      }

      return { shouldStop: false };
    } catch (error) {
      this.logger.error('应急止损检查失败:', error);
      return {
        shouldStop: true,
        reason: '应急检查失败，出于安全考虑停止交易',
      };
    }
  }
}